package org.dxy.middleware.dynamic.thread.pool.application.command.commandhandler;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dxy.middleware.dynamic.thread.pool.domain.command.RefreshThreadPoolConfigCommand;
import org.dxy.middleware.dynamic.thread.pool.domain.model.ThreadPoolAggregate;
import org.dxy.middleware.dynamic.thread.pool.domain.port.IThreadPoolRepository;
import org.dxy.middleware.dynamic.thread.pool.domain.port.IDynamicThreadPoolService;
import org.dxy.middleware.dynamic.thread.pool.infrastructure.adapter.ThreadPoolQueryRepository;
import org.dxy.middleware.dynamic.thread.pool.type.ThreadPoolNotFoundException;
import org.springframework.stereotype.Component;

/**
 * @ description:
 * @ author: dxy
 * @ createTime: 2025/10/2 11:00
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class RefreshThreadPoolConfigCommandHandler {
    private final IThreadPoolRepository IThreadPoolRepository;
    private final IDynamicThreadPoolService dynamicThreadPoolService;
    private final ThreadPoolQueryRepository threadPoolQueryRepository;


    public void handle(RefreshThreadPoolConfigCommand command) {
        // 1. 先从仓储里查找已有聚合
        ThreadPoolAggregate threadPoolAggregate = IThreadPoolRepository.findByAppNameAndThreadPoolName(command.appName() ,command.threadPoolName());


        if (threadPoolAggregate == null) {
            log.error("未找到线程池配置,command:{}",command);
            String message = String.format("未找到线程池配置: app=%s, pool=%s",
                    command.appName(), command.threadPoolName());
            throw new ThreadPoolNotFoundException(message);
        }

        // 3. 刷新配置
        threadPoolAggregate.refresh(command);
        // 更新运行时线程池配置
        dynamicThreadPoolService.refresh(threadPoolAggregate);
        // 4. 更新线程池缓存
        IThreadPoolRepository.refresh(threadPoolAggregate);
        // 更新读模型
        threadPoolQueryRepository.update(threadPoolAggregate);

        log.info("线程池配置已刷新: app={}, pool={}, corePoolSize={}, maximumPoolSize={}, queueCapacity={}",
                command.appName(), command.threadPoolName(),
                command.corePoolSize(), command.maximumPoolSize(), command.queueCapacity());
    }
}
